#include "rs485_comm_analyse.h"
#include "device_resource.h"
#include "modbus_rtu_comm.h"
#include "print_rtt.h"
#include "private_mqtt_publish_msg.h"
#include "rs485_frame_assemble.h"
#include "string.h"
#include "unit_status_common.h"
RS485_COM_ST r485_cs;
// 22 个从机
// 每个从机 24个控制变量
// 每个点4个字节，
// 为了凑够整数个，把控制变量调整为34个 ，则控制节点数 22*34=748,每个项目的长度4个字节。缓冲器的地址用的是FSMC 的SDRAM

// 7次查询，放2个循环的量，取每次最大的量，即 7*2*128=238

int rs485_com_comm_and_relay_unit_status_init(struct one_com_status *ocs)
{
  ocs->status = 0;
  ocs->request_current_slave_index = 0xFF;
  ocs->request_current_slave_step = 0xFF;
  memset(ocs->slave_unit, 1, sizeof(ocs->slave_unit) * ONE_COM_CONTANT_SLAVE_UNIT_NUM);
  return 0;
}

uint8_t get_box_from_bound_index(uint8_t index)
{
  if (index <= 5)
  {
    return index * 20 + 1;
  }
  else if ((index >= 6) && (index <= 12))
  {
    return (index - 6) * 20 + 2;
  }
  return 0;
}
/**
 * @brief 根据 box 值反向查找原始 index (0~12)
 * @param box_value 输入的 box 编号（如 1, 21, 2, 22 等）
 * @return 对应的 index (0~12)，失败返回 0xFF
 */
uint8_t get_index_from_bound_box(uint8_t box_value)
{
  // 第一组：box % 20 == 1，且值为 1, 21, 41, 61, 81, 101
  if ((box_value % 20) == 1)
  {
    uint8_t idx = (box_value - 1) / 20;
    if (idx <= 5) // 确保 index 在 0~5 范围内
    {
      return idx;
    }
  }
  // 第二组：box % 20 == 2，且值为 2, 22, 42, 62, 82, 102, 122
  else if ((box_value % 20) == 2)
  {
    uint8_t offset = (box_value - 2) / 20;
    if (offset <= 6) // offset 0~6 → index 6~12
    {
      return offset + 6;
    }
  }
  // 非法输入
  return 0xFF;
}
uint8_t get_request_step(uint8_t index)
{
  return ((uint8_t)REQUEST_STATUS_1800_181B + index);
}
int get_request_relay_unit_index(struct one_com_status *ocs)
{
  if ((ocs->request_current_slave_step == 0xFF) || (ocs->request_current_slave_step >= 6))
  {
    ocs->request_current_slave_index++;
    ocs->request_current_slave_step = 0;
  }
  else
  {
    ocs->request_current_slave_step++;
  }
  if (ocs->request_current_slave_index >= ONE_COM_CONTANT_SLAVE_UNIT_NUM)
  {
    ocs->request_current_slave_index = 0;
    ocs->request_current_slave_step = 0;
  }
  ocs->cro_st.ctrl_unit_index = ocs->request_current_slave_index;
  ocs->cro_st.order_type = get_request_step(ocs->request_current_slave_step);
  if (ocs->slave_unit[ocs->request_current_slave_index].enable_status == 0)
  {
    return -1;
  }
  return 0;
}
int get_need_send_to_relay_order(struct one_com_status *ocs, uint8_t *send_data, uint16_t *send_lenth)
{
  BaseType_t xStatus;
  // 收到信号,转换成命令，塞进去。
  xStatus = xQueueReceive(xCtrlUnitQueueHandle, &ocs->cro_st.ctrl_unit_index, pdMS_TO_TICKS(0));
  if (xStatus != pdPASS)
  {
    if (0 != get_request_relay_unit_index(ocs))
    {
      return -1;
    }
  }
  else
  {
    LOG_COLOR(YELLOW, "send from queue index:%d\n", ocs->cro_st.ctrl_unit_index);
  }
  return assemble_ctrl_request_relay_unit_frame(&ocs->cro_st, send_data, send_lenth);
}
void analyse_receive_response(struct one_com_status *ocs, int ret, uint8_t *receive_byte, uint16_t receive_lenth)
{
  uint8_t ctrl_unit_box = get_box_from_bound_index(ocs->cro_st.ctrl_unit_index);
  if (ret == -1)
  {
    // LOG_ERROR("index:%d box %d not online!\r\n", ocs->cro_st.ctrl_unit_index, ctrl_unit_box);
    ocs->slave_unit[ocs->cro_st.ctrl_unit_index].online_status = 0;
    ocs->request_current_slave_step = 0xFF; // 不在线，直接跳过下一个。
    return;
  }
  if (ctrl_unit_box == 0)
  {
    return;
  }
  if (ctrl_unit_box != receive_byte[0])
  {

    if (show_rs485 == 1)
    {
      LOG_ERROR("ruquest box!=receive box!\r\n");
    }
    return;
  }
  if (check_receive_frame_crc(receive_byte, receive_lenth) != 0)
  {

    if (show_rs485 == 1)
    {
      LOG_ERROR("modbus crc check failed!\r\n");
    }

    return;
  }

  if (show_rs485 == 1)
  {
    LOG_INFO("modbus crc check passed!\r\n");
  }

  switch (ocs->cro_st.order_type)
  {
    //  case REQUEST_STATUS:
    //    return 0;
  case REQUEST_STATUS_1800_181B: //2
    if (modbus_parse_1800_181B(receive_byte, receive_lenth, swap_all_data) == 0)
    {
      uint8_t channel = ocs->cro_st.ctrl_unit_index;
      compare_with_message2_1800_181B_status(&send_message[channel].message2, swap_all_data);

      if (show_rs485 == 1)
      {
        LOG_INFO("ALAYSE_1800_181B OK!\r\n");
      }
      return;
    }
    else
    {

      if (show_rs485 == 1)
      {
        LOG_ERROR("ALAYSE_1800_181B ERROR!\r\n");
      }
      return;
    }
  case REQUEST_STATUS_1824_1828: //2--4
    if (modbus_parse_1824_1828(receive_byte, receive_lenth, swap_all_data) == 0)
    {

      uint8_t channel = ocs->cro_st.ctrl_unit_index;
      compare_with_message2_1824_1828_status(&send_message[channel].message2, swap_all_data);

      if (show_rs485 == 1)
      {
        LOG_INFO("modbus_parse_1824_1828 OK!\r\n");
      }
      return;
    }
    else
    {

      if (show_rs485 == 1)
      {
        LOG_ERROR("modbus_parse_1824_1828 ERROR!\r\n");
      }
      return;
    }
  case REQUEST_STATUS_18A4_18B5:
    if (modbus_parse_18A4_18B5(receive_byte, receive_lenth, swap_all_data) == 0)
    {
      uint8_t channel = ocs->cro_st.ctrl_unit_index;

      if (show_rs485 == 1)
      {
        LOG_INFO("modbus_parse_18A4_18B5 OK!\r\n");
      }
      compare_with_message2_18A4_18B5_status(&send_message[channel].message2, swap_all_data);
      device_time_tickets = device_time_ms_tickets / 1000;
      if (((device_time_tickets)-send_message[channel].message2.last_send_time) >= 300)
      {
        send_message[channel].message2.need_updata_flag = 1;
      }
      if (send_message[channel].message2.need_updata_flag == 1)
      {
        send_message[channel].message2.last_send_time = device_time_tickets;
        uint8_t box = get_box_from_bound_index(channel);
        if (box == 0xFF)
        {
          return;
        }
        publish_message2_status(publish_id++, box, &send_message[channel].message2);
        send_message[channel].message2.need_updata_flag = 0;
      }
      return;
    }
    else
    {

      if (show_rs485 == 1)
      {
        LOG_ERROR("modbus_parse_18A4_18B5 ERROR!\r\n");
      }
      return;
    }
  case REQUEST_STATUS_1900_190E:
    if (modbus_parse_1900_190E(receive_byte, receive_lenth, swap_all_data) == 0)
    {

      if (show_rs485 == 1)
      {
        LOG_INFO("modbus_parse_1900_190E OK!\r\n");
      }
      return;
    }
    else
    {

      if (show_rs485 == 1)
      {
        LOG_ERROR("modbus_parse_1900_190E ERROR!\r\n");
      }
      return;
    }
  case REQUEST_STATUS_3000_3009: //1
    if (modbus_parse_3000_3009(receive_byte, receive_lenth, swap_all_data) == 0)
    {

      if (show_rs485 == 1)
      {
        LOG_INFO("modbus_parse_3000_3009 OK!\r\n");
      }
      uint8_t channel = ocs->cro_st.ctrl_unit_index;
      compare_with_message1_3000_3009_status(&send_message[channel].message1, swap_all_data);
      return;
    }
    else
    {

      if (show_rs485 == 1)
      {
        LOG_ERROR("modbus_parse_3000_3009 ERROR!\r\n");
      }
      return;
    }

  case REQUEST_STATUS_3016_301E: //1
    if (modbus_parse_3016_301E(receive_byte, receive_lenth, swap_all_data) == 0)
    {

      if (show_rs485 == 1)
      {
        LOG_INFO("modbus_parse_3016_301E OK!\r\n");
      }
      uint8_t channel = ocs->cro_st.ctrl_unit_index;
      compare_with_message1_3016_301E_status(&send_message[channel].message1, swap_all_data);
      return;
    }
    else
    {

      if (show_rs485 == 1)
      {
        LOG_ERROR("modbus_parse_3016_301E ERROR!\r\n");
      }
      return;
    }
  case REQUEST_STATUS_302E_3036: //1
    if (modbus_parse_302E_3036(receive_byte, receive_lenth, swap_all_data) == 0)
    {

      if (show_rs485 == 1)
      {
        LOG_INFO("modbus_parse_302E_3036 OK!\r\n");
      }
      uint8_t channel = ocs->cro_st.ctrl_unit_index;
      compare_with_message1_302E_3036_status(&send_message[channel].message1, swap_all_data);
      device_time_tickets = device_time_ms_tickets / 1000;
      if (((device_time_tickets)-send_message[channel].message1.last_send_time) >= 3600)
      {
        send_message[channel].message1.need_updata_flag = 1;
      }
      if (send_message[channel].message1.need_updata_flag == 1)
      {
        send_message[channel].message1.last_send_time = device_time_tickets;
        uint8_t box = get_box_from_bound_index(channel);
        publish_message1_status(publish_id++, box, &send_message[channel].message1);
        send_message[channel].message1.need_updata_flag = 0;
      }

      return;
    }
    else
    {

      if (show_rs485 == 1)
      {
        LOG_ERROR("modbus_parse_302E_3036 ERROR!\r\n");
      }
      return;
    }
  default:
    break;
  }
}
